package com.wang.hellohibernate.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.LinkedHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

abstract class AnnotationUtil{
	static final Logger logger = LoggerFactory.getLogger(AnnotationUtil.class);

	protected abstract void process(Annotation annotation, Field field);
	
	public AnnotationUtil(Object entity, Class annotationFilter)
	{
		Class clazz = (Class) entity.getClass();
		do
		{
			Field[] fields = clazz.getDeclaredFields();
			for(Field field: fields)
			{
				Annotation[] annotations = field.getAnnotations();

				for(Annotation annotation: annotations)
				{
					if(null != annotationFilter)
					{
						if(!annotation.annotationType().equals(annotationFilter))
						{
							continue;
						}
					}
					process(annotation, field);
				}
			}
			clazz = clazz.getSuperclass();
		}
		while(null != clazz);
	}

	@SuppressWarnings("unchecked")
	protected static String getAttributeValue(Annotation annotation, String attributeName)
	{
		String columName = null;
		InvocationHandler innerProxy = Proxy.getInvocationHandler(annotation);
		try {
			Field memberValuesField = innerProxy.getClass().getDeclaredField("memberValues");
			boolean isAccessible = memberValuesField.isAccessible();
			memberValuesField.setAccessible(true);
			LinkedHashMap<String, Object> memberValues = (LinkedHashMap<String, Object>)(memberValuesField.get(innerProxy));
			columName = (String) memberValues.get(attributeName);
			memberValuesField.setAccessible(isAccessible);
		} catch (Exception e) {
			logger.error(e.getMessage());
			throw new RuntimeException(e);
		}

		return columName;
	}
}